package test

import (
	"codejy/assignmentstrategy"
	"codejy/globalfunc"
	"codejy/store"
	"codejy/structdef"
	"codejy/typedefault"
	"strings"
)

type Instance struct {
	Addr        string
	ThreadStore *structdef.ThreadStore
	Addr1       string
}

// 创建实例
func (a *Instance) CreateTypeDefault(addr string, threadStore *structdef.ThreadStore, parameter ...string) {
	//获取实例的值
	var addr1 = parameter[0]
	//判断不能是空
	if addr1 == "" {
		panic("第一个参数不能为空")
	}
	//判断是否是实例
	if !store.IsInstanceExist(threadStore, addr1) {
		panic(addr1 + "不是实例")
	}
	instance := &Instance{
		Addr:        addr,
		ThreadStore: threadStore,
		Addr1:       addr1, //传入的实例地址
	}
	store.AddTypeDefaultInstanceStore(threadStore, a.GetTypeName(), addr, instance)
}
func (a *Instance) ParameterProcessing(parameter []string) []string {
	//排除前后""
	for i := range parameter {
		s := parameter[i]
		if strings.HasPrefix(s, "\"") && strings.HasSuffix(s, "\"") {
			s = s[1 : len(s)-1]
			parameter[i] = s
		}
	}
	return parameter
}

func (a *Instance) GetData() interface{} {
	return a.Addr1
}

func (a *Instance) ToStr() string {
	return ""
}

// 获取实例类型名称
func (a *Instance) GetInstanceTypeName() string {
	prop, _ := store.GetInstanceProp(a.ThreadStore, a.Addr1)
	typeName, _ := prop["@TYPENAME@"] //获取实例的类型名称
	return typeName.Value
}

// 修改实例的指定属性的值
func (a *Instance) SetInstanceProp(name string, value string) {
	var variableType = globalfunc.ExecuteFunc("CodeAnalysis", a.ThreadStore, value).(int)
	prop := store.SetInstanceProp(a.ThreadStore, a.Addr1, structdef.NewVarDefinitionValue(name, value, variableType))
	if !prop {
		panic("修改实例的指定属性的值失败,请检查属性名称是否正确,实例属性是否存在")
	}
}

// 动态函数调用
func (a *Instance) MethodCall(parameter string) string {
	funcArgs, b := typedefault.GetTypeDefaultValue[[]string](a.ThreadStore, "List", parameter)
	if !b {
		panic("参数错误,参数必须是List类型")
	}
	var funName = funcArgs[0]
	if funName == `""` {
		panic("错误::::::参数错误,第一个参数不能为空,第一个参数是函数名称")
	}
	//去掉"
	funName = funName[1 : len(funName)-1]
	prop, _ := store.GetInstanceProp(a.ThreadStore, a.Addr1)
	typeName, _ := prop["@TYPENAME@"]  //获取实例的类型名称
	scope, _ := prop["@TYPEFILEPATH@"] //获取实例的类型名称
	typeDefinition := store.GetTypeDefinition(scope.Value, typeName.Value)
	definition, p := typeDefinition.Methods[funName]
	restore := store.NweStatusRestore(a.ThreadStore, func() string {
		a.ThreadStore.CurrentInstanceAddress = a.Addr1
		if p {
			globalfunc.ExecuteFunc("ExecuteTypeMethod", a.ThreadStore, funName, definition, funcArgs)
		} else {
			panic("错误::::::" + typeName.Value + "类型中没有" + funName + "行为方法的定义")
		}
		//获取函数返回值
		variable1, p1 := store.GetVariable(a.ThreadStore, funName)
		if !p1 {
			return ""
		}
		return variable1.Value
	})
	return restore
}

// 浅拷贝实例
func (a *Instance) Copy() string {
	prop, _ := store.GetInstanceProp(a.ThreadStore, a.Addr1)
	typeName, _ := prop["@TYPENAME@"] //获取实例的类型名称
	var map1 = make(map[string]string)
	for k, v := range prop {
		//排除掉类型名称
		//排除@TYPENAME@和@TYPEFILEPATH@
		if k == "@TYPENAME@" || k == "@TYPEFILEPATH@" {
			continue
		}
		map1[k] = v.Value
	}
	var instaddr = assignmentstrategy.CreateInstanceMapNotInit(a.ThreadStore, typeName.Value, map1)
	return instaddr
}

func (f *Instance) GetDef() string {
	return `
		@CodeManual(def="new("Instance",实例变量)",des="实例变量动态工具类型")
		type Instance{
			def init{
				core&CreateTypeDefault($1)
			}
			@CodeManual(def="getTypeName()",des="获取实例类型名称")
			def getTypeName{
				to core&GetInstanceTypeName()
			}

			@CodeManual(def="setField(属性名称,属性值)",des="修改或添加实例的指定属性的值")
			def setField{
				core&SetInstanceProp($1,$2)
			}
			@CodeManual(def="invoke(函数名称,参数列表)",des="动态函数调用")
			def invoke{
				to core&MethodCall($realArgs)
			}
			@CodeManual(def="copy()",des="浅拷贝实例")
			def copy{
				to core&Copy()
			}
		}
	`
}
func init() {
	typedefault.RegisterTypeDefault(&Instance{})
}

func (f *Instance) GetTypeName() string {
	return "Instance"
}
